import { onUnmounted, ref } from 'vue'
import * as TWEEN from '@tweenjs/tween.js'

export default function () {
  let timer = null
  let frameId = null
  let scrollList = []
  let listLen = 0
  let distance = ref(60) // 每次动画的位移距离，也是容器的高度
  let duration = 500 // 动画的持续时间
  let delay = 1000 // 每次动画的间隔时间
  let current = 0 // 当前项的序号
  let tweenStatus = 'complete' // 补间动画状态：play, complete

  const currentList = ref([]) // 当前参与动画的项
  const move = ref(0) // 补间动画的位移

  // 动画开始前，要更新需要渲染的元素，并重置位移
  function modifyCurrentList() {
    let end = current + 2
    if (listLen <= 0) {
      currentList.value = []
    } else if (listLen === 1) {
      currentList.value = [scrollList[0]]
    } else if (end > listLen) {
      currentList.value = [scrollList[listLen - 1], scrollList[0]]
    } else {
      currentList.value = scrollList.slice(current, end)
    }

    move.value = 0
  }

  // 每次完成动画后，等待1秒，开启下一次动画
  function oneLoop() {
    if (tweenStatus === 'complete' && listLen > 1) {
      clearTimeout(timer)
      timer = setTimeout(() => {
        createTween()
      }, delay)
    }
  }

  // 创建动画
  function createTween() {
    const coords = { value: 0 }
    tweenStatus = 'play'
    // 补间动画
    const tween = new TWEEN.Tween(coords)
      .to({ value: distance.value }, duration)
      .easing(TWEEN.Easing.Quadratic.Out)
      .onStart(() => {
        // 每次开始，都先更新要渲染的元素
        modifyCurrentList()
      })
      .onUpdate(() => {
        // 动画中更新位移
        move.value = coords.value
      })
      .onComplete(() => {
        tweenStatus = 'complete'
        // 将当前激活序号加1
        current = current < listLen - 1 ? current + 1 : 0
        // 启动下一次动画
        oneLoop()
      })
      .start()

    // 帧循环
    function animate(time) {
      tween.update(time)
      tweenStatus === 'complete'
        ? window.cancelAnimationFrame(frameId)
        : (frameId = requestAnimationFrame(animate))
    }
    // 启动帧循环
    frameId = requestAnimationFrame(animate)
  }

  // 暂停
  function pause() {
    clearTimeout(timer)
  }
  // 继续
  function resume() {
    oneLoop()
  }

  // 移除当前项，在动画完成后可进行
  function removeCurrent() {
    if (tweenStatus === 'complete') {
      scrollList.splice(current, 1)
      listLen = scrollList.length
      current = current <= 0 ? listLen - 1 : current - 1
      modifyCurrentList()
      // listLen > 1 ? createTween() : clean()
    }
  }

  // 清理状态
  function clean() {
    clearTimeout(timer)
    cancelAnimationFrame(frameId)
  }

  function restart({
    list = [],
    height = 60,
    duration: iDuration = 500,
    delay: iDelay = 1000,
  }) {
    clean()

    distance.value = height
    duration = iDuration
    delay = iDelay

    scrollList = list
    listLen = scrollList.length
    current = 0
    tweenStatus = 'complete'

    modifyCurrentList()
    oneLoop()
  }

  onUnmounted(() => {
    clean()
  })

  return {
    currentList,
    height: distance,
    move,
    start: restart,
    pause,
    resume,
    removeCurrent,
  }
}
